/*
 *
 *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  SPDX-License-Identifier: Apache-2.0
 *
 */
import { Base64 } from 'js-base64';
import { getFileName } from './request';
import JSZip from 'jszip';

export interface Dictionary<T> {
  [index: string]: T;
}

export const PAGE_SIZE_OPTIONS = [10, 20, 30, 50, 100];

/**
 * 表格列过滤器工具函数
 */
export const tableFilter = {
  all: 'all',
};

export function saveAs(fileName: string, href: string | Blob) {
  const link = document.createElement('a');
  link.download = fileName;
  if (typeof href === 'string') {
    link.href = href;
  } else {
    link.href = URL.createObjectURL(href);
  }
  link.click();
}

/**
 *
 * @param headerOrFilename 对象应该是header对象
 * @param blob
 */
export function saveBlobAs(headerOrFilename: string | object, blob: Blob | string) {
  let filename;
  if (typeof headerOrFilename === 'object') {
    filename = getFileName(headerOrFilename);
  } else {
    filename = headerOrFilename;
  }
  const blobUrl = URL.createObjectURL(blob instanceof Blob ? blob : new Blob([blob]));
  const link = document.createElement('a');
  link.download = Base64.isValid(filename) ? Base64.decode(filename) : filename;
  link.href = blobUrl;
  link.click();
}

export function pick<T, K extends keyof T>(obj: T, paths: K[] = []): Pick<T, K> {
  return paths.reduce((res: any, k) => {
    if (k in obj) {
      res[k] = obj[k];
    }
    return res;
  }, {});
}

export function omit<T, K extends keyof T>(obj: T, paths: K[] = []): Exclude<T, K> {
  return paths.reduce(
    (res: any, k) => {
      if (k in res) {
        delete res[k];
      }
      return res;
    },
    { ...obj },
  );
}

export function safeParseArrayStr(str: string) {
  try {
    return JSON.parse(str) || [];
  } catch (e) {
    return [];
  }
}

export async function delay(second: number) {
  return new Promise((resolve) => window.setTimeout(resolve, second * 1000));
}

/**
 * 'foo=unicorn&ilike=pizza'
 */
export function stringifyQueryParams(obj: Dictionary<string | number | boolean>) {
  return Object.keys(obj)
    .reduce((res: string[], k) => {
      res.push(`${k}=${obj[k]}`);
      return res;
    }, [])
    .join('&');
}

export function keyBy<T>(arr: T[], key: keyof T): Dictionary<T> {
  return arr.reduce((res: any, item) => {
    res[item[key]] = item;
    return res;
  }, {});
}

// 切割url search
export function splitUrl(url: string) {
  const searchItem: string = url?.split('?')[1] || '';
  const result: Iterable<any> = searchItem.split('&').map((item: string) => item?.split('='));
  return new Map(result);
}

// 共识策略
export const Consensus: { [index: number]: string } = {
  0: 'SOLO',
  1: 'TBFT',
  2: 'MBFT',
  3: 'MAXBFT',
  4: 'RAFT',
  5: 'DPOS',
  10: 'POW',
};

/**
 * 根据文件数据数组下载zip文件包
 * @param list zip包内文件
 * @param list[i].data 文件数据
 * @param list[i].name 文件名
 * @param list[i].fileType 文件内容数据类型
 * @param list[i].dataType 数据格式 默认base64
 * @param pkgName
 */
export function downloadZipByTexts(
  list: {
    data: string;
    name: string;
    fileType: string;
    dataType?: string;
  }[],
  pkgName: string,
) {
  const zip = new JSZip();
  try {
    list.forEach(({ data, name, fileType, dataType = 'base64' }) => {
      const blobPart = dataType === 'base64' ? Base64.decode(data) : data;
      const option = fileType ? { type: fileType } : {};
      const blob = new Blob([blobPart], option);
      zip.file(name, blob);
    });
    zip.generateAsync({ type: 'blob' }).then((content) => {
      // depend file-saver
      saveAs(pkgName, content);
    });
  } catch (e) {
    console.error(e);
  }
}
export const isOlderThanVersion = (currentVersion: string, compareVersion: string) => {
  const COMPAREVERSIONS = compareVersion.split('.');
  const CURRENTVERSIONS = currentVersion.split('.');
  for (let i = 0; i < CURRENTVERSIONS.length; i++) {
    const current = parseInt(CURRENTVERSIONS[i], 10);
    const compare = COMPAREVERSIONS[i] ? parseInt(COMPAREVERSIONS[i]) : 0;
    if (current < compare) {
      return true;
    }
    if (current === compare) {
      continue;
    } else {
      return false;
    }
  }
  if (COMPAREVERSIONS.length > CURRENTVERSIONS.length) {
    return true;
  }
  return false;
};

const version = '1.5.2';

export const checkInstallPlugin = () => {
  if (!(window as any).chainMaker || isOlderThanVersion((window as any).chainMaker.version, version)) {
    return false;
  }
  return true;
};
